<template>
  <n-space vertical justify="space-between">
    <n-card>
      <!-- 输入框 -->
      <n-tabs type="line" animated>
        <n-tab-pane name="基础配置">
          <div class="file-info">
            <div class="title">左键复制</div>
            <div
              :style="{
                width: '100%',
              }"
            >
              <n-input
                v-model:value="inputValue"
                placeholder="聚焦输入框后，左键点击客户端气泡，复制任意内容到此处"
                clearable
                @keyup.enter="handleInputEnter"
                spellcheck="false"
              />
            </div>
          </div>
          <div class="file-info">
            <div class="title">平台类型</div>
            <div
              :style="{
                width: '100%',
              }"
            >
              <n-radio-group v-model:value="platformValue" name="radiogroup">
                <n-space>
                  <n-radio
                    v-for="plat in platforms"
                    :key="plat.value"
                    :value="plat.value"
                    :disabled="plat?.disabled || wssPort > 0"
                    @change="handleRadioChange"
                  >
                    <div class="radio-item">
                      <img :src="plat.icon" style="width: 1rem; height: 1rem" />
                      <div>{{ plat.label }}</div>
                    </div>
                  </n-radio>
                </n-space>
              </n-radio-group>
            </div>
          </div>
          <div class="file-info">
            <div class="title">WS端口</div>
            <div
              class="path"
              :style="{
                display: 'flex',
                alignItems: 'center',
              }"
            >
              <n-tag
                v-if="!dynamicTags.length || wssPort > 0"
                size="small"
                :style="{
                  marginRight: '0.25rem',
                }"
              >
                {{ wssPort || "No Port" }}
                <template v-if="wssPort > 0" #icon>
                  <n-icon :component="CheckmarkCircle" />
                </template>
              </n-tag>
              <n-dynamic-tags
                v-if="!wssPort"
                v-model:value="dynamicTags"
                size="small"
                :max="1"
              >
              </n-dynamic-tags>
            </div>
            <n-button
              :type="wssPort > 0 ? 'error' : 'primary'"
              secondary
              @click="startOrStopServer"
              :loading="startOrStopServerLoading"
              size="tiny"
            >
              {{ wssPort > 0 ? "关闭" : "启动" }}
            </n-button>
            <div
              :style="{
                display: 'flex',
                alignItems: 'center',
              }"
            >
              <n-checkbox
                v-model:checked="autoSendBaseData"
                size="small"
                label="自动发送基础信息"
                @update:checked="changeAutoSendBaseData"
                :disabled="wssPort > 0"
              />
              <n-tooltip trigger="hover">
                <template #trigger>
                  <n-icon><InfoCircleOutlined /></n-icon>
                </template>
                勾选后，当客户端连接成功时自动向其发送客服信息，当前会话等基础消息
              </n-tooltip>
            </div>
          </div>
          <div class="file-info">
            <div class="title">数据文件</div>
            <div class="path">{{ filePath || "No base json file path" }}</div>
            <n-button secondary @click="readFile" size="small" v-if="!filePath">
              选择文件
            </n-button>
            <n-button
              v-if="filePath"
              secondary
              type="error"
              @click="clearFile"
              size="small"
            >
              清除文件
            </n-button>
          </div>
          <div
            class="file-info"
            :style="{
              alignItems: 'flex-start',
            }"
          >
            <div class="title">已识别类型</div>
            <n-space vertical>
              <!-- <div v-if="!filePath" class="path">{{ "No data type" }}</div> -->
              <!-- <n-space>
                <n-tag v-for="type in dataTypes" :key="type" size="small" type="success">
                  {{ type }}
                </n-tag>
              </n-space> -->
              <n-space>
                <n-tag
                  v-for="t in defaultDataTypes"
                  :key="t"
                  size="small"
                  round
                  :type="dataTypes.includes(t) ? 'success' : 'default'"
                  :disabled="!dataTypes.includes(t)"
                >
                  {{ t }}
                  <template v-if="dataTypes.includes(t)" #icon>
                    <n-icon :component="CheckmarkCircle" />
                  </template>
                </n-tag>
              </n-space>
            </n-space>
          </div>
          <div
            class="file-info"
            :style="{
              alignItems: 'flex-start',
            }"
          >
            <div
              v-if="dataTypes.includes('message') || dataTypes.includes('newMsg')"
              class="title"
            >
              模拟发送
            </div>
            <n-space>
              <n-button
                v-if="dataTypes.includes('message')"
                secondary
                round
                type="primary"
                @click="send"
                size="small"
                :disabled="!filePath || wssPort === 0"
              >
                顾客发送
              </n-button>
              <n-button
                v-if="dataTypes.includes('newMsg')"
                round
                secondary
                type="info"
                @click="sendNewMsg"
                size="small"
                :disabled="!filePath || wssPort === 0"
              >
                客服发送
              </n-button>

              <n-button
                v-if="isConnected"
                round
                type="error"
                secondary
                @click="closeClient"
                size="small"
                :disabled="wssPort === 0"
              >
                关闭客户端
              </n-button>
            </n-space>
          </div>
        </n-tab-pane>
      </n-tabs>
    </n-card>
    <!-- 显示文件内容 -->
    <n-card title="日志">
      <template #header-extra>
        <n-select
          v-model:value="showType"
          :options="options"
          size="tiny"
          :style="{
            width: '5.5rem',
            marginRight: '0.5rem',
          }"
        />
        <n-switch
          v-model:value="showParseContent"
          size="small"
          :style="{
            marginRight: '0.5rem',
          }"
        />
        <n-button class="extra-btn" @click="refreshLogs" size="tiny" secondary>
          <template #icon>
            <n-icon><ReloadOutline /></n-icon>
          </template>
        </n-button>
        <n-button
          v-if="logs.length > 0"
          class="extra-btn"
          @click="clearLogs"
          size="tiny"
          secondary
          type="error"
        >
          <template #icon>
            <n-icon><DeleteOutlined /></n-icon>
          </template>
        </n-button>
      </template>
      <n-list v-if="filterLogs.length > 0">
        <n-list-item v-for="log in filterLogs">
          <div class="log-item">
            <div class="header">
              <div v-if="log.from">
                <n-tag
                  size="small"
                  :bordered="false"
                  :type="log?.from === 1 ? 'success' : 'info'"
                  >{{ log.from === 1 ? "服务端" : "客户端" }}</n-tag
                >
              </div>
              <div class="type">
                <n-tag size="small" :bordered="false" :type="log.tagType">{{
                  log.type
                }}</n-tag>
              </div>
              <div class="time">
                <n-tag
                  size="small"
                  :color="{ color: '#f5f5f5', textColor: '#666666' }"
                  :bordered="false"
                  >{{ formatTime(log.time) }}</n-tag
                >
              </div>
              <div class="fromNow">
                <n-tag
                  size="small"
                  :color="{ color: '#f5f5f5', textColor: '#666666' }"
                  :bordered="false"
                  >{{ fromNow(log.time) }}</n-tag
                >
              </div>
              <n-button
                v-if="log.from"
                secondary
                size="tiny"
                @click="copyText(log.message)"
              >
                复制
              </n-button>
            </div>
            <div class="message">
              {{ showParseContent ? renderLogMessage(log) : log?.message }}
            </div>
          </div>
        </n-list-item>
      </n-list>
      <n-empty v-else description="暂无日志" />
    </n-card>
  </n-space>
</template>

<script setup lang="ts">
import {
  NButton,
  NIcon,
  NSpace,
  NTag,
  NList,
  NListItem,
  NEmpty,
  NDynamicTags,
  NRadio,
  NRadioGroup,
  NCard,
  NTabs,
  NTabPane,
  NCheckbox,
  NTooltip,
  NInput,
  NSelect,
  NSwitch,
} from "naive-ui";
import { CheckmarkCircle, ReloadOutline } from "@vicons/ionicons5";
import { DeleteOutlined, InfoCircleOutlined } from "@vicons/antd";
import { createDiscreteApi } from "naive-ui";
import { computed, ref } from "vue";
import { copyText, formatTime, fromNow } from "../utils";
import qn from "@/assets/qn.png";
import jm from "@/assets/jm.png";
import pdd from "@/assets/pdd.png";
import dd from "@/assets/dd.svg";

const showType = ref("all");
const inputValue = ref("");
const autoSendBaseData = ref(true);
const showParseContent = ref(true);
// 客户端是否连接
const isConnected = ref(false);
const dynamicTags = ref<string[]>([]);
const platformValue = ref("qn");
const options = [
  {
    label: "全部",
    value: "all",
  },
  {
    label: "服务端",
    value: "server",
  },
  {
    label: "客户端",
    value: "client",
  },
  {
    label: "其他",
    value: "other",
  },
];
const platforms = [
  {
    label: "千牛",
    value: "qn",
    icon: qn,
    disabled: false,
  },
  {
    label: "拼多多",
    value: "pdd",
    icon: pdd,
    disabled: false,
  },
  {
    label: "抖店",
    value: "dd",
    icon: dd,
    disabled: false,
  },
  {
    label: "京麦",
    value: "jd",
    icon: jm,
    disabled: false,
  },
];

const filterLogs = computed(() => {
  if (showType.value === "all") {
    return logs.value;
  }
  if (showType.value === "other") {
    return logs.value.filter((log) => ![1, 2].includes(log.from));
  }
  return logs.value.filter((log) => log.from === (showType.value === "server" ? 1 : 2));
});

const logs = ref<any[]>([]);
const startOrStopServerLoading = ref(false);
const wssPort = ref(0);
const { message, notification } = createDiscreteApi([
  "message",
  "dialog",
  "notification",
  "loadingBar",
  "modal",
]);

const defaultDataTypes = [
  "currentCsr",
  "currentConv",
  "message",
  "remote_his_message",
  "newMsg",
];
const dataTypes = ref<string[]>([]);
const filePath = ref<string>("");
const fileContent = ref<string>("");

// 展示日志内容
const renderLogMessage = (log: any) => {
  const type = log?.type;
  if (type === "ToSend") {
    const msg = JSON.parse(log.message);
    const method = msg?.ly_params?.method;
    // return `发送消息：${
    //   msg?.ly_params?.text || msg?.ly_params?.image || msg?.ly_params?.video
    // }`;
    switch (method) {
      case "sendtext":
        return `[文本]：${msg?.ly_params?.text}`;
      case "sendimage":
        return `[图片]：${msg?.ly_params?.image}\n[图片url]：${msg?.urls ?? "无"}`;
      case "sendvideo":
        return `[视频]：${msg?.ly_params?.video}\n[视频url]：${msg?.urls ?? "无"}`;
      default:
        return log.message;
    }
  }
  return log.message;
};

// 打开devtools
const handleInputEnter = () => {
  if (inputValue.value === "kikolove") {
    window.electron.ipcRenderer.send("open-devtools");
  }
};

// 点击事件（通知主进程读取json文件）
const send = () => {
  try {
    window.electron.ipcRenderer.send("send-data");
  } catch (error) {
    console.log(error);
  }
};

// 点击事件（通知主进程读取json文件）
const sendNewMsg = () => {
  try {
    window.electron.ipcRenderer.send("send-data", "newMsg");
  } catch (error) {
    console.log(error);
  }
};

const changeAutoSendBaseData = (val: boolean) => {
  console.log(val);
  window.electron.ipcRenderer.send("sign-auto-send", val);
};

const handleRadioChange = (e: Event) => {
  const val = (e.target as HTMLInputElement).value;
  platformValue.value = val;
  const documentTitleMaps = {
    qn: "千牛接待工作台",
    pdd: "拼多多工作台",
    dd: "抖店[商家]工作台",
    jd: "咚咚融合工作台",
  };
  const oldTitle = document.title.split("-")[0];
  document.title = oldTitle + ` - ${documentTitleMaps[val]}`;
};
const closeClient = () => {
  try {
    window.electron.ipcRenderer.send("close-client");
    notification.info({
      title: "已关闭客户端",
      duration: 1500,
    });
  } catch (error) {
    console.log(error);
  }
};

const readFile = async () => {
  try {
    const { filePaths } = await window.electron.ipcRenderer.invoke("open-file-dialog");
    if (filePaths.length > 0) {
      console.log("Selected file path:", filePaths[0]);
      // 选在的文件路径
      filePath.value = filePaths[0];

      fileContent.value = JSON.stringify(
        await window.electron.ipcRenderer.invoke("read-file", filePaths[0])
      );

      console.log(fileContent.value);
      // 在把选选在的文件路径传给主进程
      // window.electron.ipcRenderer.send('send', filePaths[0]);
      // 你可以在这里处理文件路径
    }
  } catch (error) {
    console.error("Error opening file dialog:", error);
  }
};

const clearFile = async () => {
  notification.info({
    title: "文件已清除",
    content: filePath.value,
    duration: 1500,
  });
  dataTypes.value = [];
  filePath.value = "";
  fileContent.value = "";
  await window.electron.ipcRenderer.invoke("clear-file");
};

const clearLogs = () => {
  notification.success({
    title: "日志已清除",
    content: `共清除${logs.value.length}条日志`,
    duration: 1500,
  });
  logs.value = [];
};

const refreshLogs = async () => {
  logs.value = [...logs.value];
  message.success("日志已刷新");
};

const startOrStopServer = async () => {
  const start = async () => {
    startOrStopServerLoading.value = true;
    try {
      const res = await window.electron.ipcRenderer.invoke(
        "start-server",
        platformValue.value,
        Number(dynamicTags.value[0]) || 50001
      );
      if (res) {
        wssPort.value = res;
        // message.success("Socket服务器启动成功");
        notification.success({
          title: "Socket服务器启动成功",
          content: `端口号：${wssPort.value}`,
          duration: 1500,
        });
      }
    } catch (error) {
      console.log(error);
      // message.error("启动失败");
      notification.error({
        title: "启动失败",
        content: `端口号：${wssPort.value}`,
        duration: 1500,
      });
    } finally {
      await new Promise((resolve) => {
        setTimeout(() => {
          resolve(null);
        }, 100);
      });
      startOrStopServerLoading.value = false;
    }
  };
  const stop = async () => {
    startOrStopServerLoading.value = true;
    try {
      const res = await window.electron.ipcRenderer.invoke("stop-server");
      wssPort.value = 0;
      if (res) {
        // message.success("已关闭服务器");
        notification.info({
          title: "已关闭服务器",
          duration: 1500,
        });
      }
    } catch (error) {
      console.log(error);
      // message.error("关闭失败");
      notification.error({
        title: "关闭失败",
        duration: 1500,
      });
    } finally {
      await new Promise((resolve) => {
        setTimeout(() => {
          resolve(null);
        }, 100);
      });
      startOrStopServerLoading.value = false;
    }
  };
  console.log(wssPort.value);
  if (wssPort.value > 0) {
    stop();
  } else {
    start();
  }
};

const init = async () => {
  // 统一处理ipc事件
  const ipcHandlers = {
    "render-log": (
      _event: any,
      log: {
        type: string;
        message: string;
        data: any;
        tagType: string;
        time: number;
      }
    ) => {
      log.time = Date.now();
      if (log.tagType === "error") {
        notification.error({
          title: log.type,
          content: log.message,
          duration: 1500,
        });
      }
      logs.value.unshift(log);
    },
    "render-client-isConnected": (_event: any, connected: boolean) => {
      isConnected.value = connected;
    },
    "render-data-types": (_event: any, types: string[]) => {
      dataTypes.value = types;
    },
  };

  // 批量注册事件监听
  Object.entries(ipcHandlers).forEach(([event, handler]) =>
    window.electron.ipcRenderer.on(event, handler)
  );

  // 设置文档标题
  const [baseTitle] = document.title.split("-");
  document.title = `${baseTitle} - 千牛接待工作台`;
};

init();
</script>

<style lang="less" scoped>
.extra-btn:not(:last-child) {
  margin-right: 0.5rem;
}
.header-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 100%;
  .left-bar {
    font-size: 16px;
    font-weight: bold;
  }
  .right-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    -webkit-app-region: no-drag;
  }
}

.log-item {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 10px;
  line-height: 1.5;
  .header {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 0.125rem;
  }
  .message {
    padding: 10px;
    font-size: 12px;
    color: #888;
    background: #f5f5f5;
    white-space: pre-wrap;
    // 超出三行省略
    overflow: auto;
    max-height: 5rem;
    border-radius: 5px;
    word-break: break-all;
  }
}
.file-info {
  margin-bottom: 1rem;
  display: flex;
  align-items: center;
  gap: 10px;
  line-height: 1.5;
  user-select: none;
  &:last-child {
    margin-bottom: 0;
  }
  .title {
    font-size: 14px;
    font-weight: bold;
    min-width: 4.5rem;
  }
  .path {
    font-size: 14px;
    color: #888;
    max-width: 400px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .radio-item {
    display: flex;
    align-items: center;
    gap: 5px;
  }
}

.file-content {
  margin-top: 20px;
  font-size: 14px;
  color: #888;
  max-width: 400px;
}
:deep(.n-layout-sider-scroll-container) {
  padding: 0 !important;
}
</style>
